package com.appengine.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.nio.charset.Charset;
import java.util.Arrays;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.protocol.HTTP;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONStringer;
import android.util.Log;

public class JsonUtils {
	
	// setup connection to server timeout(15s)
	private static int ConnectionTimeOut = 15000;

	// setup read json from response timeout (30s)
	private static int ReadTimeOut = 30000;

	// setup read buffer array size
	private static int ReadBuffSize = 256;

	// parse all data(byte wise) from rd
	private static String readAll(Reader rd) throws IOException {
		StringBuilder sb = new StringBuilder();

		int cp = 0;

		// -- changed to read byte array instead of char only ;

		/* fase performance algorithm ---- */
		char buff[] = new char[ReadBuffSize];
		char trimmedBuff[] = null;
		// read bytes
		while ((cp = rd.read(buff)) != -1) {

			// build string
			// sb.append((char) cp);

			if (cp < ReadBuffSize) {
				trimmedBuff = new char[cp];
				System.arraycopy(buff,0, trimmedBuff,0, cp);
				sb.append(trimmedBuff);
			} else {
				sb.append(buff);
			}
			 
	    /* slow performance algorithm
		while ((cp = rd.read()) != -1) {

			// build string
			sb.append((char) cp);
		}*/
		}
		return sb.toString();
	}

	// given a URL, read a and return the JsonObject posted to it(given that it
	// was properly posted)
	public static JSONObject readJsonFromUrl(String url) throws IOException,
			JSONException {
		InputStream is = null;
		try {
			// open url connection
			URLConnection con = new URL(url).openConnection();

			// setup connection timeout properties
			con.setConnectTimeout(ConnectionTimeOut);
			con.setReadTimeout(ReadTimeOut);

			// get input stream from connection
			is = con.getInputStream();

			// get reader from connection
			BufferedReader rd = new BufferedReader(new InputStreamReader(is,
					Charset.forName("UTF-8")));

			// get all bytes from input stream
			String jsonText = readAll(rd);

			// convert json bytes to json object
			JSONObject json = new JSONObject(jsonText);

			// return json object
			return json;
		} catch (SocketTimeoutException e) {
			Log.e("timeout on reading json", e.toString());
		} catch (Exception e) {
			Log.e("error on reading json", e.toString());
		} finally {
			// close url connection
			is.close();
		}

		return null;
	}

	public static boolean SendJsonStringer(JSONStringer jsonStr,
			String ServletURL) {
		HttpPost request = new HttpPost(ServletURL);

		try {
			// set timeout
			HttpParams httpParams = new BasicHttpParams();
			HttpConnectionParams.setConnectionTimeout(httpParams, 2500);
			HttpConnectionParams.setSoTimeout(httpParams, 2500);

			// add json as entity
			StringEntity entity = new StringEntity(jsonStr.toString());

			// set entity content type
			entity.setContentType("application/json;charset=UTF-8");

			// set entity content encoding in HTTP header
			entity.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,
					"application/json;charset=UTF-8"));

			// add entity to HTTP request
			request.setEntity(entity);

			// Send request to WCF service
			DefaultHttpClient httpClient = new DefaultHttpClient(httpParams);

			// execute request
			HttpResponse response = httpClient.execute(request);

			Log.w("json response", response.toString());
		} catch (UnsupportedEncodingException e) {
			Log.e("unsupported encoding error", e.toString());
			return false;
		} catch (ClientProtocolException e) {
			Log.e("client protocol error", e.toString());
			return false;
		} catch (IOException e) {
			Log.e("IO error", e.toString());
			return false;
		} catch (Exception e) {
			Log.e("error on sending json stringer", e.toString());
			return false;
		}

		return true;
	}

}
